package com.scorpio.pay.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.scorpio.common.service.impl.BaseServiceImpl;
import com.scorpio.common.utils.StringUtils;
import com.scorpio.pay.domain.PayCallbackEntity;
import com.scorpio.pay.enums.PayCallbackStatusEnum;
import com.scorpio.pay.enums.PayTypeEnum;
import com.scorpio.pay.mapper.PayCallbackMapper;
import com.scorpio.pay.service.CallbackService;
import com.scorpio.pay.service.PayCallbackService;
import com.scorpio.redis.cachelock.RedisLock;
import com.scorpio.sdk.service.WXPayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class PayCallbackServiceImpl extends BaseServiceImpl<PayCallbackMapper, PayCallbackEntity> implements PayCallbackService {

    @Autowired
    private WXPayService wxPayService;

    @Autowired
    private RedisLock redisLock;

    @Autowired
    private CallbackService callbackService;

    @Override
    public int save(PayCallbackEntity entity) {
        return baseDao.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public int updateStatus(Long id, PayCallbackStatusEnum statusEnum) {
        return baseDao.updateStatus(id, statusEnum.getValue());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean handlePay(PayCallbackEntity entity) {
        if (PayTypeEnum.WeChatPay.getValue().equals(entity.getType())) {
            String body = wxPayService.decryptToString(entity.getBody());
            if (StringUtils.isEmpty(body)) {
                return false;
            }
            JSONObject parameter = JSONObject.parseObject(body);
            if (parameter != null) {
                String trade_state = parameter.getString("trade_state");
                if ("SUCCESS".equals(trade_state)) {
                    //商户订单号
                    String out_trade_no = parameter.getString("out_trade_no");
                    //微信订单号
                    String transaction_id = parameter.getString("transaction_id");
                    JSONObject amount = parameter.getJSONObject("amount");
                    int total = amount.getInteger("total");
                    String key = PayTypeEnum.WeChatPay.getInfo() + ":" + out_trade_no;
                    if (redisLock.lock(key, 5)) {
                        try {
                            callbackService.wxPayNotification(out_trade_no, transaction_id, total);
                            updateStatus(entity.getId(), PayCallbackStatusEnum.STATUS3);
                            return true;
                        } catch (Exception e) {
                            updateStatus(entity.getId(), PayCallbackStatusEnum.STATUS2);
                            throw e;
                        } finally {
                            redisLock.unlock(key);
                        }
                    }
                }
            }
        }
        return false;
    }

}
